/*!
 * \file task_adaptors.hpp
 * \brief 任务适配器
 *
 * \details 此文件包含任务函数对象的适配器。
 *          
 *          提供的适配器包括：
 *          - task_func：标准任务函数对象
 *          - prio_task_func：优先级任务函数对象
 *          - looped_task_func：循环任务函数对象
 *          
 *          这些适配器为不同类型的任务执行提供了灵活的封装机制，
 *          支持优先级控制、循环执行等高级功能。
 *
 * Copyright (c) 2005-2007 Philipp Henkel
 *
 * Use, modification, and distribution are  subject to the
 * Boost Software License, Version 1.0. (See accompanying  file
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 *
 * http://threadpool.sourceforge.net
 *
 */

#ifndef THREADPOOL_TASK_ADAPTERS_HPP_INCLUDED
#define THREADPOOL_TASK_ADAPTERS_HPP_INCLUDED

#include <boost/smart_ptr.hpp>
#include <boost/function.hpp>
#include <boost/thread.hpp>
#include <time.h>

namespace boost { namespace threadpool
{

  /*!
   * \brief 标准任务函数对象
   *
   * \details 此函数对象包装一个无参数且返回void的函数。
   *          通过调用operator()来调用被包装的函数。
   *          
   *          这是线程池中最基本的任务类型，适用于：
   *          - 简单的无返回值任务
   *          - 不需要参数传递的操作
   *          - 基础的异步执行场景
   *          
   *          基于boost function库实现，提供了类型擦除
   *          和函数对象的统一接口。
   *
   * \see boost function library
   */ 
  typedef function0<void> task_func;

  /*!
   * \brief 优先级任务函数对象
   *
   * \details 此函数对象包装一个task_func对象并绑定一个优先级。
   *          prio_task_func可以使用operator<进行比较，实现偏序关系。
   *          通过调用operator()来调用被包装的任务函数。
   *          
   *          特点：
   *          - 支持基于优先级的任务排序
   *          - 兼容优先级调度器
   *          - 提供任务执行的优先级控制
   *          - 实现了比较运算符以支持排序
   *          
   *          适用场景：
   *          - 需要任务优先级控制的系统
   *          - 关键任务需要优先执行的场景
   *          - 基于重要性排序的任务队列
   *
   * \see prio_scheduler
   */ 
  class prio_task_func
  {
  private:
    unsigned int m_priority;  //!< 任务函数的优先级
    task_func m_function;     //!< 任务的函数对象

  public:
    typedef void result_type; //!< 指示函数对象的结果类型

  public:
    /*!
     * \brief 构造函数
     * \param priority 任务的优先级
     * \param function 任务的函数对象
     */
    prio_task_func(unsigned int const priority, task_func const & function)
      : m_priority(priority)
      , m_function(function)
    {
    }

    /*!
     * \brief 执行任务函数
     * 
     * \details 调用被包装的任务函数，如果函数对象有效则执行
     */
    void operator() (void) const
    {
      if(m_function)
      {
        m_function();
      }
    }

    /*!
     * \brief 基于优先级实现偏序关系的比较运算符
     * \param rhs 要比较的对象
     * \return 如果*this的优先级小于右侧对象的优先级则返回true，否则返回false
     * 
     * \details 用于优先级队列中的任务排序，优先级值越小表示优先级越高
     */
    bool operator< (const prio_task_func& rhs) const
    {
      return m_priority < rhs.m_priority; 
    }

  };  // prio_task_func

  /*!
   * \brief 循环任务函数对象
   *
   * \details 此函数对象包装一个返回布尔值的线程函数对象。
   *          通过调用operator()来调用被包装的任务函数，并在固定时间间隔内
   *          重复执行，直到返回false。时间间隔可以为零。
   *          
   *          重要特性：
   *          - 支持定时循环执行
   *          - 可配置的执行间隔
   *          - 自动的线程让渡机制
   *          - 基于返回值的循环控制
   *          
   *          注意事项：
   *          请注意，只要任务在循环中，线程池的线程就会被占用。
   *          因此需要合理设计循环条件和间隔时间。
   *          
   *          适用场景：
   *          - 需要周期性执行的任务
   *          - 监控和轮询操作
   *          - 定时数据处理
   *          - 心跳和状态检查
   */ 
  class looped_task_func
  {
  private:
    function0<bool> m_function;   //!< 任务的函数对象
    unsigned int m_break_s;       //!< 间隔时间的秒数部分
    unsigned int m_break_ns;      //!< 间隔时间的纳秒数部分

  public:
    typedef void result_type; //!< 指示函数对象的结果类型

  public:
    /*!
     * \brief 构造函数
     * \param function 要循环执行的任务函数对象，当返回false时停止循环
     * \param interval 首次执行前和后续执行间的最小间隔时间（毫秒）
     * 
     * \details 将间隔时间转换为秒和纳秒分量以提高精度
     */
    looped_task_func(function0<bool> const & function, unsigned int const interval = 0)
      : m_function(function)
    {
      m_break_s  = interval / 1000;
      m_break_ns = (interval - m_break_s * 1000) * 1000 * 1000;
    }

    /*!
     * \brief 执行任务函数
     * 
     * \details 在首次执行前等待指定间隔，然后循环执行任务函数。
     *          每次执行后等待指定间隔，或在无间隔时让渡线程控制权。
     *          当任务函数返回false时停止循环。
     */
    void operator() (void) const
    {
      if(m_function)
      {
        if(m_break_s > 0 || m_break_ns > 0)
        { // 首次执行前先睡眠一段时间
          xtime xt;
          xtime_get(&xt, boost::TIME_UTC_);
          xt.nsec += m_break_ns;
          xt.sec += m_break_s;
          thread::sleep(xt); 
        }

        while(m_function())
        {
          if(m_break_s > 0 || m_break_ns > 0)
          {
            xtime xt;
            xtime_get(&xt, boost::TIME_UTC_);
            xt.nsec += m_break_ns;
            xt.sec += m_break_s;
            thread::sleep(xt); 
          }
          else
          {
            thread::yield(); // 对其他线程保持公平性
          }
        }
      }
    }

  }; // looped_task_func

} } // namespace boost::threadpool

#endif // THREADPOOL_TASK_ADAPTERS_HPP_INCLUDED

